#include <mitsuba/render/shapegroup.h>
#include <mitsuba/core/properties.h>

NAMESPACE_BEGIN(mitsuba)

/**!

.. _shape-shapegroup:

Shape group (:monosp:`shapegroup`)
----------------------------------

.. pluginparameters::

 * - (Nested plugin)
   - :paramtype:`shape`
   - One or more shapes that should be made available for geometry instancing

This plugin implements a container for shapes that should be made available for geometry instancing.
Any shapes placed in a shapegroup will not be visible on their own—instead, the renderer will
precompute ray intersection acceleration data structures so that they can efficiently be referenced
many times using the :ref:`shape-instance` plugin. This is useful for rendering things like forests,
where only a few distinct types of trees have to be kept in memory. An example is given below:

.. code-block:: xml

    <!-- Declare a named shape group containing two objects -->
    <shape type="shapegroup" id="my_shape_group">
        <shape type="ply">
            <string name="filename" value="data.ply"/>
            <bsdf type="roughconductor"/>
        </shape>
        <shape type="sphere">
            <transform name="to_world">
                <scale value="5"/>
                <translate y="20"/>
            </transform>
            <bsdf type="diffuse"/>
        </shape>
    </shape>

    <!-- Instantiate the shape group without any kind of transformation -->
    <shape type="instance">
        <ref id="my_shape_group"/>
    </shape>

    <!-- Create instance of the shape group, but rotated, scaled, and translated -->
    <shape type="instance">
        <ref id="my_shape_group"/>
        <transform name="to_world">
            <rotate x="1" angle="45"/>
            <scale value="1.5"/>
            <translate z="10"/>
        </transform>
    </shape>

 */

template <typename Float, typename Spectrum>
class ShapeGroupPlugin final : public ShapeGroup<Float, Spectrum> {
public:
    MTS_IMPORT_BASE(ShapeGroup)
    MTS_IMPORT_TYPES()

    ShapeGroupPlugin(const Properties &props) : Base(props) { }

    MTS_DECLARE_CLASS()
};

MTS_IMPLEMENT_CLASS_VARIANT(ShapeGroupPlugin, ShapeGroup)
MTS_EXPORT_PLUGIN(ShapeGroupPlugin, "Shape group plugin")

NAMESPACE_END(mitsuba)
